#装饰器参数：
'''
1.被装饰函数无参数
2.被装饰的函数有参数
3.被装饰的函数有不定长参数
'''
#1.无参数的函数（被装饰的函数无参数）
#装饰函数
def test(fn):    #fn形参代表真正业务函数的函数名
    def inner():
        print('这是inner')
        fn()
    return inner

#方法一
def t1():
    print('哈哈哈')
t = test(t1)
t()
print('\n')

#方法二
@test
def t2():
    print('哈哈哈')
t2()
print('\n')


#2.被装饰的函数有参数
#装饰函数
def exam(fn):
    def inner(a,b):
        print('inner函数中值：%s,%s'%(a,b))
        fn(a,b)    #真正的业务函数
    return inner
@exam
def test1(a1,b1):     #真正的业务函数定义
    print('Result is:',(a1+b1))
test1(1,2)
print('\n')


#多层嵌套
def exam1(fn):
    def funa(x,y):
        print('hello',x,y)
        def inner(a,b):
            print('inner函数中值：%s,%s'%(a,b))
            fn(a,b)    #真正的业务函数
        return inner
    return funa
@exam1
def test2(a1,b1):
    print('Result is:',(a1+b1))
test2(1,2)(3,4)    #1,2传递给了x,y；3,4传递给了a,b
print('\n')


#3.被装饰的函数有不定长参数
#必选参数-->默认参数-->可变参数-->命名关键字参数和关键字参数
def funa(fn):
    def inner(*args,**kwargs):
        print(f'我开始计算：{fn.__name__}函数了')
        fn(*args,**kwargs)    #真正的业务函数
        print('执行完成')
    return inner
@funa
def add(*a,**b):
    print(a)
    print(b)
add(2,3,4,5,6,a=1,b=3)          #关键字传参方式 key = value




